package com.summer.data.rs.extractor;

import com.summer.data.dialect.Dialect;
import com.summer.data.exception.BaseException;
import com.summer.data.rs.Extractor;
import com.summer.data.rs.map.*;
import com.summer.data.table.BaseTable;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author 345480567@qq.com
 */

public class  ManyRecordExtractor<T> implements Extractor<List<T>> {

    private AbstractResultSetMapFun<T> mapFun;

    public ManyRecordExtractor(AbstractResultSetMapFun<T> mapFun) {
        this.mapFun = new ResultSetMapLogFun<T>(mapFun);
    }

    @Override
    public List<T> extract(ResultSet rs, Dialect dialect) {
        mapFun.setDialect(dialect);
        try {
            List<T> mapList = new ArrayList<>();
            mapFun.mapBegin(rs);
            while (rs.next()) {
                T map = mapFun.map(rs, dialect);
                mapList.add(map);
            }
            mapFun.mapEnd(rs);

            return mapList;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new BaseException(e);
        }
    }

    public static ManyRecordExtractor<Map<String, Object>> createMapExtractor() {
        ResultSetToMapFun mapFun = new ResultSetToMapFun();
        return new ManyRecordExtractor<Map<String, Object>>(mapFun);
    }

    public static <T> ManyRecordExtractor<T> createObjectExtractor(Class<T> clazz) {
        if (BaseTable.class.isAssignableFrom(clazz)) {
            return (ManyRecordExtractor<T>)createTableExtractor((Class<BaseTable>) clazz);
        }
        ResultSetToDtoFun<T> mapFun = new ResultSetToDtoFun<T>(clazz);
        return new ManyRecordExtractor<T>(mapFun);
    }

    public static <T extends BaseTable> ManyRecordExtractor<T> createTableExtractor(Class<T> clazz) {
        ResultSetToTableFun<T> mapFun = new ResultSetToTableFun<T>(clazz);
        return new ManyRecordExtractor<T>(mapFun);
    }

}

